import numpy as np
import pandas as pd
import os

# 中值平均值滤波
def MedianAvg_Filter(window_left, window_right, arr):
  size = len(arr)
  result = []
  for i in range(window_left, size-window_right):
    # 滑窗
    temp = []
    for j in range(-window_left, window_right+1):
      temp.append(arr[i+j])
    temp.sort()
    # 可以去掉最大值后，取中位数的平均值
    median_mean = []
    for m in range(1, len(temp)-1):
      median_mean.append(temp[m])

    result.append(np.mean(median_mean))
  return result

#自定义灰色预测函数
def GM11(x0):
    x1 = x0.cumsum() #1-AGO序列
    z1 = (x1[:len(x1)-1] + x1[1:])/2.0 #紧邻均值（MEAN）生成序列
    z1 = z1.reshape((len(z1),1))
    B = np.append(-z1, np.ones_like(z1), axis = 1)
    Yn = x0[1:].reshape((len(x0)-1, 1))
    [[a],[b]] = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Yn) #计算参数
    f = lambda k: (x0[0]-b/a)*np.exp(-a*(k-1))-(x0[0]-b/a)*np.exp(-a*(k-2)) #还原值
    delta = np.abs(x0 - np.array([f(i) for i in range(1,len(x0)+1)]))
    C = delta.std()/x0.std()
    P = 1.0*(np.abs(delta - delta.mean()) < 0.6745*x0.std()).sum()/len(x0)
    return f, a, b, x0[0], C, P  #返回灰色预测函数、a、b、首项、方差比、小残差概率

'''
对外调用接口;
提供给外部其他Python文件调用接口.
'''
def data_process(data,url):
    if url:
       df = pd.read_excel(url)
    else:
        df = data
    df.columns = ['y']
    # 滤波后的数据
    data1 = df[:1000]
    data_filter = np.array(MedianAvg_Filter(10, 10, data1['y'])).reshape(-1, 1)

    # 用前1000轮预测后100轮
    train = pd.DataFrame(data_filter)
    test = df[-100:]

    # 预测
    for i, ind in enumerate(test.index):
        pred = []
        f = GM11(train.values)[0]
        pred.append(f(1 + len(train)))
        train.loc[ind, :] = np.array(pred)
    pred = train.iloc[-100:, :]
    pred.columns = ['y']
    pred = np.array(pred).reshape(-1, 1)
    pred = pred.tolist()
    return pred

if __name__ =="__main__":
    # 读取文件
    url = 'Grey_model_data.xlsx'
    data = pd.read_excel('Grey_model_data.xlsx')
    pred = data_process(data,url)

    # 输出预测值
    print('Predict:', pred)